<template lang="pug">
.shop-cart-wrapper
  .shop-cart-sticky(@click="toggleList")
    .icon
      .icon-wrapper(:class="{'highlight':totalCount>0}")
        Bubble.totalCount.highlight( 
                          v-if="totalCount>0"
                          :num="totalCount")            
        i.icon.iconfont.iconshop_car(:class="{'highlight':totalPrice>0}")
    .totalPrice ￥{{totalPrice}}
    .delivery-price 另需配送费￥{{deliveryPrice}}元
    .pay(:class="{'highlight':totalPrice>minPrice}"
          @click="pay") {{payDesc}}
    //- 下落小球
    //- 启示位置在购物车中
    .ball-wrapper
      .ball(v-for="(ball,index) in balls")
        transition(@before-enter="beforeDrop" @enter="dropping" @after-enter="afterDrop")
          .outter(v-show="ball.show")
            .inner.drop-ball-inner-hook
  //- 弹出式已选中商品列表
  .popup-list-container(v-show="shopListVisible")
    ShopCartList(:selectedProductions="selectedProductions"
                 :enableClickTwice="enableClickTwice"
                 @sendVisible="onVisible"
                 @addEvent="onAdd"
                 ref="shopCartList")
</template>

<script>
import {mapState} from 'vuex'
import Bubble from '../bubble/bubble'
import ShopCartList from '../shop-cart-list/shop-cart-list'


// 定义同时绘制的下落小球的总数
const BALL_LEN = 20
const ballInnerHook = 'drop-ball-inner-hook'

// 初始化下落小球数组
function createBalls() {
  let ret = []
  for(let i=0;i<BALL_LEN;i++){
    ret.push({
      show:false
    })
  }
  return ret
}

export default {

  props: {

    selectedProductions: {
      type: Array,
      default() {
        return []
      }
    },

    deliveryPrice: {
      type: Number,
      default: 0
    },

    minPrice: {
      type: Number,
      default: 0
    },

    // 解决cube-scroll组件点击事件触发两次bug
    enableClickTwice: {
      type: Boolean,
      default: true
    }

  },

  data() {
    return {
      // 所有下落小球=正在下落的(显示）+ 已经落入购物车中的（隐藏)
      balls: createBalls(),
      // 正在下落的小球(显示）
      dropBalls: [],
      // 显示购物车列表
      shopListVisible: false
    }
  },

  computed: {

    // 全局变量
    ...mapState({
      // 用户
      user: 'user'
    }),

    totalCount() {
      let retCount = 0
      this.selectedProductions.forEach((production)=>{
        retCount += production.count
      })
      return retCount
    },

    totalPrice() {
      let retPrice = 0
      this.selectedProductions.forEach((production)=>{
        retPrice += production.price*production.count
      })
      return retPrice
    },

    payDesc() {
      if(this.totalPrice===0){
        return `￥${this.minPrice}起送`
      }
      if(this.totalPrice<this.minPrice){
        let diff = this.minPrice - this.totalPrice
        return `还差${diff}元起送`
      }else{
        return '去结算'
      }
    }

  },

  components: {
    Bubble,
    ShopCartList
  },

  methods: {
    
    // 将新加的小球添加到下落小球数组中
    // el:从点击添加按钮事件传递过来的添加按钮DOM对象
    // 从el获取下落小球启始位置
    drop(el) {
      for(let i=0; i<this.balls.length; i++) {
        const ball = this.balls[i]
        if(!ball.show){
          ball.show=true
          ball.el=el
          this.dropBalls.push(ball)
          return
        }
      }
    },

    // 小球开始下落
    // el:小球外层div(class="outter")
    // 由vue的transition触发
    // 当外层(outter)div的v-show切换为true时执行
    beforeDrop(el) {
      // 找到最后下落的小球
      const ball = this.dropBalls[this.dropBalls.length-1]
      // 获取添加按钮的包络巨型
      const rect = ball.el.getBoundingClientRect()

      // 计算小球x轴偏移量=
      // 添加按钮.left-购物车的margin-left
      // x轴正方向超右
      const x = rect.left - 40
      // const x = -30

      // 计算小球y轴偏移量=
      // -(window.innerHeight-添加按钮.top-购物车.top)
      // y轴正方向朝下
      const y = -(window.innerHeight - rect.top - 22)
      // 显示下落小球
      el.style.display = ''
      // 为下落小球样式
      // 将下落小球移动到添加按钮处
      // 1.将下落小球的外部包络div延y轴移动到添加按钮处
      let ystyle = `translate3d(0, ${y}px, 0)`
      el.style.transform = ystyle
      el.style.webkitTransform = ystyle
      const inner = el.getElementsByClassName(ballInnerHook)[0]
      // 2.为下落小球的内部div延x轴移动到添加按钮处
      let xstyle = `translate3d(${x}px, 0, 0)`
      inner.style.transform = xstyle
      inner.style.webkitTransform = xstyle
    },

    // 小球正在下落钩子函数
    // el:小球外层div(class="outter")
    // done:回调函数
    dropping(el, done) {
      // 触发重绘
      this._reflow = document.body.offsetHeight
      // 归位-还是归在原来的位置
      el.style.transform = 'translate3d(0, 0, 0)'
      el.style.webkitTransform = 'translate3d(0, 0, 0)'
      const inner = el.getElementsByClassName(ballInnerHook)[0]
      inner.style.transform = 'translate3d(0, 0, 0)'
      inner.style.webkitTransform = 'translate3d(0, 0, 0)'
      // 监听动画结束时间，并调用回调函数done
      el.addEventListener('transitionend', done)
    },

    // 小球正在下落结束钩子函数
    // el:小球外层div(class="outter")
    afterDrop(el) {
      // 找到第一个添加的小球
      // 从下落小球数组中删除第一个添加的下落小球
      const ball = this.dropBalls.shift()
      if (ball) {
          // 隐藏小球
          ball.show = false
          // 隐藏下落小球
          el.style.display = 'none'
      }
    },

    // 显示/隐藏购物车列表
    toggleList() {

      console.log('shopListVisible:')
      console.log(this.shopListVisible)

      if(!this.shopListVisible) {
        if(!this.totalCount) {
          return
        }
        console.log('启动this.shopCartList.show')
        this.$refs.shopCartList.show()
      } else {
        this.$refs.shopCartList.hide()
      }
    },

    // 接收shop-cart-list子组件中的显隐状态值
    onVisible(visible) {
      this.shopListVisible = visible
      console.log('shopListVisible:')
      console.log(this.shopListVisible)
    },

    // 将添加按钮的DOM对象传递给ShopCart组件
    // el:从shop-cart-list传递来的添加按钮DOM对象
    onAdd(el) {
      // 调用ShopCart组件的drop方法
      // 触发小球下落动画
      this.drop(el)
    },

    // 支付按钮点击事件
    pay(e) {
      if(!this.totalPrice)
        return
      if(this.totalPrice<this.minPrice)
        return
      
      // 若用户未登陆，弹出登陆，确定后跳转到登陆tab页签
      if(!(this.user) || !(this.user.openid)) {
        console.log('user:')
        console.log(this.user)
        this.$createDialog({
          type: '警告',
          title: '登陆',
          content: '请先登陆，再支付。',
          icon: 'cubeic-alert',
          onConfirm: (e) => {
            // 跳转到用户页签
            this.$store.dispatch('gotoUserTab')
          }
        }).show()
        e.stopPropagation()
        return
      }

      // 若用户已登陆，创建订单
      this.dialogPay = this.$createDialog({
        type: 'confirm',
        content: `请您支付${this.totalPrice}元`,
        confirmBtn: {
            text: '确定',
            active: true,
            disable: false
        },
        cancelBtn: {
            text: '取消',
            active: false
        },
        onConfirm: async () => {

          // 1.创建订单
          const secleteds = _.map(this.selectedProductions, 
            (item,index)=>{
              return {
                id: item.id,
                count: item.count
              }
            }
          )
          
          const newOrder = {
            openid: this.user.openid,
            productions: secleteds
          }
          await this.$store.dispatch('createOrder', newOrder)

          // 2.清空购物车
          this.selectedProductions.forEach((production)=>{
            if(production.count) {
              production.count = 0
            }
          })

        },
        onCancel: () => {

        }
      })
      this.dialogPay.show()
      e.stopPropagation()
    }

  }

}
</script>

<style lang="stylus" scoped>
@import '../../static/common/stylus/variable'
@import "../../static/common/stylus/mixin"

.shop-cart-wrapper
  position:relative
  background:$color-background
  color:$color-light-grey
  width:100%
  height:56px
  .shop-cart-sticky
    position:relative
    z-index:100
    .icon
      display:inline-block
      position:relative
      top:-20px
      margin-left:8px
      width: 70px
      height: 70px
      border-radius: 50%;
      background:$color-background
      .icon-wrapper
        width:54px
        height:54px
        margin:8px 8px
        border-radius: 50%;
        background:$color-dark-grey
        text-align:center
        &.highlight
          background:$color-blue
        .iconshop_car
          display:inline-block
          text-align:center
          vertical-align:baseline
          line-height:54px
          top:1px
          height:100%
          width:100%
          font-size: 34px
          background:$color-dark-grey
          margin-left:0
          &.highlight
            color:$color-white
            background:$color-blue
        .totalCount
          position:absolute
          top:2px
          right:4px
          font-size:14px
          line-height:16px
    .totalPrice
      position:relative
      display:inline-block
      vertical-align:top
      line-height:56px
      margin-left:8px
    .delivery-price
      display:inline-block
      vertical-align:top
      line-height:56px
      margin-left:8px
    .pay
      display:inline-block
      float:right
      vertical-align:top
      line-height:56px
      width:100px
      text-align:center
      &.highlight
        color:$color-white
        background:$color-green
    .ball-wrapper
      .outter
        position: fixed
        left: 40px
        bottom:30px
        z-index:200
        transition: all .5s cubic-bezier(0.49, -0.29, 0.75, 0.41)
        .inner
          width: 16px
          height: 16px
          border-radius:50%
          background: $color-blue
          transition: all .5s linear
  .popup-list-container
    z-index:-100
    position:absolute
    bottom:56px
    left:0
    right:0
    height:160px
</style>
